package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.atguigu.tingshu.account.client.UserAccountFeignClient;
import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AssertUtil;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.user.service.UserPaidTrackService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {


    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;
    @Autowired
    private UserVipServiceMapper userVipServiceMapper;
    @Autowired
    private VipServiceConfigMapper vipServiceConfigMapper;
//    @Autowired
//    private UserPaidAlbumMapper userPaidAlbumMapper;
    @Autowired
    private UserPaidTrackMapper userPaidTrackMapper;

    @Autowired
    private TrackInfoFeignClient trackInfoFeignClient;

    @Override
    public UserInfoVo getUserInfoVo() {
        UserInfo userInfo = baseMapper.selectById(AuthContextHolder.getUserId());
        UserInfoVo vo = new UserInfoVo();
        BeanUtils.copyProperties(userInfo , vo);
        return vo;
    }

    @Override
    public void updateUser(UserInfo userInfo) {
        userInfo.setId(AuthContextHolder.getUserId());
        //mybatisplus生成sql时， updateById方法  会使用传入对象的id作为条件，不为空的属性值作为更新字段去更新
        baseMapper.updateById(userInfo);

    }

    @Override
    public void savePaidRecords(UserPaidRecordVo userPaidRecordVo) {
        if(CollectionUtils.isEmpty(userPaidRecordVo.getItemIdList())){
            throw new GuiguException(ResultCodeEnum.DATA_ERROR);
        }
        if(userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_VIP)){
            //用户表记录vip状态
            //查找购买的vip产品： 使用月数+当前时间
            VipServiceConfig vipServiceConfig = vipServiceConfigMapper.selectById(userPaidRecordVo.getItemIdList().get(0));
            Date vipExpireTime = new DateTime().plusMonths(vipServiceConfig.getServiceMonth()).toDate();
            //1、查询用户表vip状态
            UserInfo userInfo = baseMapper.selectById(userPaidRecordVo.getUserId());

            //vip购买记录
            UserVipService userVipService = new UserVipService();
            if(userInfo.getIsVip().intValue()!=1){
                //如果不是vip：修改用户为vip并设置过期时间  再保存vip购买记录
                userInfo.setIsVip(1);
                userInfo.setVipExpireTime(vipExpireTime);

                userVipService.setStartTime(new Date());
                userVipService.setExpireTime(new DateTime().plusMonths(vipServiceConfig.getServiceMonth()).toDate());

            }else{
                //如果是vip： 修改用户vip过期时间  再保存vip购买记录
                if(!userInfo.getVipExpireTime().before(new Date())){
                    vipExpireTime = new DateTime(userInfo.getVipExpireTime())
                            .plusMonths(vipServiceConfig.getServiceMonth()).toDate();

                    userVipService.setStartTime(userInfo.getVipExpireTime());
                    userVipService.setExpireTime(new DateTime(userVipService.getStartTime()).plusMonths(vipServiceConfig.getServiceMonth()).toDate());

                }else{
                    userVipService.setStartTime(new Date());
                    userVipService.setExpireTime(new DateTime().plusMonths(vipServiceConfig.getServiceMonth()).toDate());
                }
                userInfo.setIsVip(1);
                userInfo.setVipExpireTime(vipExpireTime);
            }
            baseMapper.updateById(userInfo);

            userVipService.setUserId(userPaidRecordVo.getUserId());
            userVipService.setOrderNo(userPaidRecordVo.getOrderNo());
            userVipServiceMapper.insert(userVipService);


        }else if(userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_ALBUM)){
            //数据库中  userId+ albumid 设置 唯一键约束
            UserPaidAlbum userPaidAlbum = new UserPaidAlbum();
            userPaidAlbum.setUserId(userPaidRecordVo.getUserId());
            userPaidAlbum.setOrderNo(userPaidRecordVo.getOrderNo());
            Long albumId = userPaidRecordVo.getItemIdList().get(0);
            userPaidAlbum.setAlbumId(albumId);
            userPaidAlbumMapper.insert(userPaidAlbum);
            //保存专辑下的所有声音购买记录
            //根据专辑id查询专辑下的所有声音id列表
            Result<List<Long>> trackIdsResult = trackInfoFeignClient.findTrackIdsByAlbumId(albumId);
            AssertUtil.resultAssert(trackIdsResult,ResultCodeEnum.DATA_ERROR);

            List<Long> trackIds = trackIdsResult.getData();
            //需要过滤掉已经过买过的声音id
            //查询当前用户 当前专辑已购买过的声音id列表
            List<Long> paidTrackIds = userPaidTrackMapper.selectList(Wrappers.lambdaQuery(UserPaidTrack.class)
                            .eq(UserPaidTrack::getAlbumId, albumId)
                            .eq(UserPaidTrack::getUserId, userPaidRecordVo.getUserId())
                            .select(UserPaidTrack::getTrackId))
                    .stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
            trackIds.stream().filter(trackId-> !paidTrackIds.contains(trackId)).forEach(trackId->{
                UserPaidTrack userPaidTrack = new UserPaidTrack();
                userPaidTrack.setUserId(userPaidRecordVo.getUserId());
                userPaidTrack.setOrderNo(userPaidRecordVo.getOrderNo());
                userPaidTrack.setTrackId(trackId);
                userPaidTrack.setAlbumId(albumId);
                userPaidTrackMapper.insert(userPaidTrack);
            });

        }else if(userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_TRACK)){
            //根据声音id查询专辑id
            Long tId = userPaidRecordVo.getItemIdList().get(0);
            Result<Long> albumIdResult = trackInfoFeignClient.findAlbumIdByTrackId(tId);
            AssertUtil.resultAssert(albumIdResult,ResultCodeEnum.DATA_ERROR);
            Long albumId = albumIdResult.getData();
            userPaidRecordVo.getItemIdList().forEach(trackId->{
                UserPaidTrack userPaidTrack = new UserPaidTrack();
                userPaidTrack.setUserId(userPaidRecordVo.getUserId());
                userPaidTrack.setOrderNo(userPaidRecordVo.getOrderNo());
                userPaidTrack.setTrackId(trackId);
                userPaidTrack.setAlbumId(albumId);
                userPaidTrackMapper.insert(userPaidTrack);
            });
        }else{
            throw new GuiguException(ResultCodeEnum.DATA_ERROR);
        }
    }

    @Override
    public boolean isSupportRefund(String orderNo) {
        //查询购买记录
        UserVipService userVipService = userVipServiceMapper
                .selectOne(Wrappers.lambdaQuery(UserVipService.class)
                        .eq(UserVipService::getOrderNo, orderNo)
                        .ge(UserVipService::getStartTime,
                                new DateTime().withTimeAtStartOfDay().toDate()));

        return userVipService!=null;
    }

//    public static void main(String[] args) {
//        System.out.println(new DateTime().withTimeAtStartOfDay().toDate());
//    }
}
